﻿#region Copyright (c) 2000-2013 Developer Express Inc.
/*
{*******************************************************************}
{                                                                   }
{       Developer Express .NET Component Library                    }
{                                                                   }
{                                                                   }
{       Copyright (c) 2000-2013 Developer Express Inc.              }
{       ALL RIGHTS RESERVED                                         }
{                                                                   }
{   The entire contents of this file is protected by U.S. and       }
{   International Copyright Laws. Unauthorized reproduction,        }
{   reverse-engineering, and distribution of all or any portion of  }
{   the code contained in this file is strictly prohibited and may  }
{   result in severe civil and criminal penalties and will be       }
{   prosecuted to the maximum extent possible under the law.        }
{                                                                   }
{   RESTRICTIONS                                                    }
{                                                                   }
{   THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES           }
{   ARE CONFIDENTIAL AND PROPRIETARY TRADE                          }
{   SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS   }
{   LICENSED TO DISTRIBUTE THE PRODUCT AND ALL ACCOMPANYING .NET    }
{   CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY.                 }
{                                                                   }
{   THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED      }
{   FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE        }
{   COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE       }
{   AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT  }
{   AND PERMISSION FROM DEVELOPER EXPRESS INC.                      }
{                                                                   }
{   CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON       }
{   ADDITIONAL RESTRICTIONS.                                        }
{                                                                   }
{*******************************************************************}
*/
#endregion Copyright (c) 2000-2013 Developer Express Inc.

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Markup;
using System.Collections;
using DevExpress.Data.Browsing;
using System.Collections.Generic;
using DevExpress.Xpf.Editors;
using System.IO;
#if !SL
using System.Data;
using UColor.WPF.DemosHelpers.Grid;
using System.ComponentModel;
#else
using PropertyDescriptor = DevExpress.Data.Browsing.PropertyDescriptor;
using UColor.WPF.NWind;
using UColor.WPF.DemosHelpers;
#endif
namespace UColor.WPF.DemosHelpers.Grid {
	[ContentProperty("Paragraph")]
	public class ParagraphContainer : Control {
		public Paragraph Paragraph { get; set; }
	}
	public abstract class MultiEditorsListBase : IList, ITypedList, IBindingList {
		#region Field Descriptions
		public List<FieldDescription> FieldDescriptions = new List<FieldDescription>() {
				new FieldDescription("ProductName", "Name", "TextEdit", "TextEdit", typeof(string), 1, -1),
				new FieldDescription("ProductID", "ID", "TextEdit (with numeric mask)","NumericTextEdit", typeof(int), 0, 1),
				new FieldDescription("EAN13", "Code", "TextEdit (with RegEx mask)" ,"RegExTextEdit", typeof(string), 9, 1),
				new FieldDescription(string.Empty, "Password", "PasswordBoxEdit", "PasswordBoxEdit", typeof(string), 14, 1),
				new FieldDescription(string.Empty, "Countries", "ButtonEdit", "ButtonEdit", typeof(string), 13, -1),
				new FieldDescription("CategoryID", "Category", "ComboBoxEdit", "ComboBoxEdit", typeof(int), 2, 13),
				new FieldDescription(string.Empty, "Country", "ComboBoxEdit (with AutoComplete)", "AutoCompleteComboBoxEdit", typeof(string), 3, 2),
				new FieldDescription("CategoryID", "Category", "SearchLookUpEdit", "SearchLookUpEdit", typeof(int), 20, 2),
				new FieldDescription("CategoryID", "Category", "LookUpEdit", "LookUpEdit", typeof(int), 21, 2),
				new FieldDescription(string.Empty, "Notes", "MemoEdit", "MemoEdit", typeof(string), 10, 13),
				new FieldDescription(string.Empty, "Date", "DateEdit", "DateEdit", typeof(DateTime), 11, 13),				
				new FieldDescription(string.Empty, "Font", "FontEdit", "FontEdit", typeof(FontFamily), 19, 13),
				new FieldDescription("UnitPrice", "Unit Price", "PopupCalcEdit", "PopupCalcEdit", typeof(double), 15, 13),
				new FieldDescription(string.Empty, "Color", "PopupColorEdit", "PopupColorEdit", typeof(Color), 16, 13),
				new FieldDescription(string.Empty, "Picture", "PopupImageEdit", "PopupImageEdit", typeof(ImageSource), 17, 13),				
				new FieldDescription("UnitsInStock", "Units In Stock", "TrackBarEdit", "TrackBarEdit", typeof(double), 5, -1),
				new FieldDescription("ReorderLevel", "Reorder Level", "ZoomTrackBarEdit", "ZoomTrackBarEdit", typeof(double), 6, 5),
				new FieldDescription(string.Empty, "Range", "RangeTrackBarEdit", "RangeTrackBarEdit", typeof(TrackBarEditRange), 7, 5),
				#if !SL
				new FieldDescription(string.Empty, "Units On Order", "ProgressBarEdit", "ProgressBarEdit", typeof(double), 18, 5),
				#endif                                
				new FieldDescription("Discontinued", "Discontinued", "CheckEdit", "CheckEdit", typeof(bool), 8, -1),
				new FieldDescription(string.Empty, "Discount", "SpinEdit", "SpinEdit", typeof(decimal), 4, -1),								
				new FieldDescription(string.Empty, "Pallete Size", "ListBoxEdit", "ListBoxEdit", typeof(string), 12, -1)
			};
		#endregion
#if !SL
		//DataRowCollection rows;
#else
		IList<Products> rows;
		IList<UColor.WPF.NWind.Categories> categories;
#endif
		public MultiEditorsListBase() {
#if SL
			rows = new List<Products>();
			foreach (Products product in NWindData.Products)
				rows.Add(product);
			categories = new List<UColor.WPF.NWind.Categories>();
			foreach (UColor.WPF.NWind.Categories category in NWindData.Categories)
				categories.Add(category);
#else
		//	rows = NWindData.Products.Table.Rows;			
#endif
			CreateDataTable();
			CreateColumnCollection();
		}
		protected internal PropertyDescriptorCollection ColumnCollection { get; protected set; }
		protected List<Dictionary<string, object>> Table { get; private set; }
		Random random = new Random();
		void CreateDataTable() {
			this.Table = new List<Dictionary<string, object>>();
			
		}
		PropertyDescriptorCollection GetProperties(object product) {
#if !SL
			//return ((ITypedList)NWindData.Products.Table.DefaultView).GetItemProperties(null);
            return null;
#else
			return TypeDescriptor.GetProperties(product);
#endif
		}
		object GetProductPropertyValue(int index, string propertyName) {
#if !SL
			//DataRowView product = NWindData.Products.Table.DefaultView[index]; 
#else
			object product = rows[index];
#endif
			//PropertyDescriptor property = GetProperties(product)[propertyName];
            return null; //property != null ? property.GetValue(product) : null;
		}
		ImageSource GetPhoto(int i) {
			if (random.Next(8) > 5)
				return null;
#if !SL
			//byte[] bytes = NWindData.Categories.Table.Rows[i % NWindData.Categories.Table.Rows.Count]["Picture"] as byte[];
#else
			byte[] bytes = categories[i % categories.Count].Picture;
#endif
            return null;// DevExpress.Xpf.Core.Native.ImageHelper.CreateImageFromStream(new MemoryStream(bytes));
		}
		FontFamily GetFont(int i) {
			IList fontSource = null;
#if SL
			fontSource = new List<object>(DevExpress.Utils.Internal.FontManager.GetFontFamilyNames());
#else
			fontSource = new List<object>(Fonts.SystemFontFamilies);
#endif
			return new FontFamily(fontSource[random.Next(fontSource.Count)].ToString());
		}
		Color GenerateRandomColor() {
			byte[] bytes = new byte[3];
			random.NextBytes(bytes);
			return Color.FromArgb(byte.MaxValue, bytes[0], bytes[1], bytes[2]);
		}
		string GenerateRandomPassword() {
			return new string('p', random.Next(3, 15));
		}
		double GenerateRandomDiscount() {
			return random.NextDouble() * 0.1d;
		}
        //string GetRandomCountry() {
        //    return NWindData.CountriesArray[random.Next(NWindData.CountriesArray.Length)];
        //}		
		public void SetPropertyValue(int rowIndex, int columnIndex, object value) {
			if (columnIndex > 0 && columnIndex <= Table.Count) {
				Table[columnIndex - 1][FieldDescriptions[rowIndex].ColumnName] = value;
				RaiseListChanged(rowIndex, columnIndex);
			}
		}
		void RaiseListChanged(int rowIndex, int columnIndex) {
			if (listChangedEventHandler == null)
				return;
			int[] rowIndexes = GetRowIndexes(rowIndex);
			foreach (int index in rowIndexes) {
				listChangedEventHandler(this, new System.ComponentModel.ListChangedEventArgs(System.ComponentModel.ListChangedType.ItemChanged, index));
			}
		}
		int[] GetRowIndexes(int rowIndex) {
			List<int> indexes = new List<int>();
			string propertyName = FieldDescriptions[rowIndex].PropertyName;
			for (int i = 0; i < Count; i++) {
				if (string.Equals(propertyName, FieldDescriptions[i].PropertyName, StringComparison.InvariantCultureIgnoreCase)) {
					indexes.Add(i);
				}
			}
			return indexes.ToArray();
		}
		protected abstract void CreateColumnCollection();
		public abstract object GetPropertyValue(int rowIndex, int columnIndex);
		#region ITypedList Interface
		PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] descs) { return ColumnCollection; }
		string ITypedList.GetListName(PropertyDescriptor[] descs) { return ""; }
		#endregion
		#region IList Interface
		public virtual int Count {
			get { return FieldDescriptions.Count; }
		}
		public virtual bool IsSynchronized {
			get { return true; }
		}
		public virtual object SyncRoot {
			get { return true; }
		}
		public virtual bool IsReadOnly {
			get { return false; }
		}
		public virtual bool IsFixedSize {
			get { return true; }
		}
		public virtual IEnumerator GetEnumerator() {
			return null;
		}
		public virtual void CopyTo(System.Array array, int fIndex) {
		}
		public virtual int Add(object val) {
			throw new NotImplementedException();
		}
		public virtual void Clear() {
			throw new NotImplementedException();
		}
		public virtual bool Contains(object val) {
			throw new NotImplementedException();
		}
		public virtual int IndexOf(object val) {
			throw new NotImplementedException();
		}
		public virtual void Insert(int fIndex, object val) {
			throw new NotImplementedException();
		}
		public virtual void Remove(object val) {
			throw new NotImplementedException();
		}
		public virtual void RemoveAt(int fIndex) {
			throw new NotImplementedException();
		}
		object IList.this[int fIndex] {
			get { return fIndex; }
			set { }
		}
		#endregion
		#region IBindingList Members
		void IBindingList.AddIndex(PropertyDescriptor property) {
			throw new NotImplementedException();
		}
		object IBindingList.AddNew() {
			throw new NotImplementedException();
		}
		bool IBindingList.AllowEdit { get { return true; } }
		bool IBindingList.AllowNew { get { return false; } }
		bool IBindingList.AllowRemove { get { return false; } }
		void IBindingList.ApplySort(PropertyDescriptor property, System.ComponentModel.ListSortDirection direction) {
			throw new NotImplementedException();
		}
		int IBindingList.Find(PropertyDescriptor property, object key) {
			throw new NotImplementedException();
		}
		bool IBindingList.IsSorted { get { return false; } }
		event System.ComponentModel.ListChangedEventHandler listChangedEventHandler;
		event System.ComponentModel.ListChangedEventHandler IBindingList.ListChanged {
			add { listChangedEventHandler += value; }
			remove { listChangedEventHandler -= value; }
		}
		void IBindingList.RemoveIndex(PropertyDescriptor property) { throw new NotImplementedException(); }
		void IBindingList.RemoveSort() { throw new NotImplementedException(); }
		System.ComponentModel.ListSortDirection IBindingList.SortDirection { get { throw new NotImplementedException(); } }
		PropertyDescriptor IBindingList.SortProperty { get { return null; } }
		bool IBindingList.SupportsChangeNotification { get { return true; } }
		bool IBindingList.SupportsSearching { get { return false; } }
		bool IBindingList.SupportsSorting { get { return false; } }
		#endregion
	}
	public class MultiEditorsListPropertyDescriptor : PropertyDescriptor {
		string propertyName;
		bool isReadOnly;
		MultiEditorsListBase list;
		int index;
		public MultiEditorsListPropertyDescriptor(MultiEditorsListBase list, int index, string propertyName, bool isReadOnly)
			: base(propertyName, null) {
			this.propertyName = propertyName;
			this.isReadOnly = isReadOnly;
			this.list = list;
			this.index = index;
		}
		public override bool CanResetValue(object component) {
			return false;
		}
		public override object GetValue(object component) {
			return list.GetPropertyValue((int)component, index);
		}
		public override void SetValue(object component, object val) {
			list.SetPropertyValue((int)component, index, val);
		}
		public override bool IsReadOnly { get { return isReadOnly; } }
		public override string Name { get { return propertyName; } }
		public override Type ComponentType { get { return list.GetType(); } }
		public override Type PropertyType { get { return typeof(object); } }
		public override void ResetValue(object component) {
		}
		public override bool ShouldSerializeValue(object component) { return true; }
	}
	public class FieldDescription {
		public FieldDescription(string propertyName, string columnName, string editorDisplayName, string templateName, Type columnType, int id, int parentId) {
			this.PropertyName = propertyName;
			this.ColumnName = columnName;
			this.EditorDisplayName = editorDisplayName;
			this.TemplateName = templateName;
			this.ColumnType = columnType;
			this.Id = id;
			this.ParentId = parentId;
		}
		public string PropertyName { get; private set; }
		public string ColumnName { get; private set; }
		public string EditorDisplayName { get; private set; }
		public string TemplateName { get; private set; }
		public Type ColumnType { get; private set; }
		public int Id { get; private set; }
		public int ParentId { get; private set; }
	}
    //public class DemoDataProviderBase {
    //    public static readonly string[] PalleteSizesStatic = new string[] { "4x4", "10x10", "16x16", "20x20", "25x25" };
    //    public string[] PalleteSizes { get { return PalleteSizesStatic; } }
    //    public string[] CountriesArray { get { return UColor.WPF.NWindData.CountriesArray; } }
    //}
}
